#include "flashexecutor.h"
#include "candriver.h"
#include "udstp.h"
#include "qjsonobject.h"

sActionFlow ActionFlow;

QString FlashExecutor::AppPath;

FlashExecutor::FlashExecutor()
{
    disconnect(&S3Timer, &QTimer::timeout, this, &FlashExecutor::Tick100ms);
    connect(&S3Timer, &QTimer::timeout, this, &FlashExecutor::Tick100ms);
    S3Timer.setTimerType(Qt::PreciseTimer);
    S3Timer.start(100);
}

void FlashExecutor::Initialization()
{
    u8TotalStep = flashInfor.count();
    u8CurrStep = 0;
    u8ReceSuccFlag = true;
    u8RunningFlag = true;
    S3TimerTick = 5000;
}

void FlashExecutor::TxProcessHandle()
{
    uint8_t showSize = 0;
    if(u8RunningFlag == true)
    {
        if(u8ReceSuccFlag == true)
        {
            udsClient.UDSSerNum = flashInfor.at(u8CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
            for(uint8_t UDSSerIndex = 0; UDSSerIndex < udsClient.SupSerItem; UDSSerIndex++)
            {
                if(udsClient.UDSSerNum == udsClient.pstUDSService[UDSSerIndex].serNum)
                {
                    QString message = "Tx:  ";
                    udsClient.pstUDSService[UDSSerIndex].pfSerNameFun(u8CurrStep, flashInfor, &udsClient.m_pstPDUMsg);
                    if(udsClient.m_pstPDUMsg.exDataLen == 0)
                    {
                        u8CurrStep++;
                        u8ReceSuccFlag = true;
                    }
                    else
                    {
                        u8ReceSuccFlag = false;
                    }
                    S3TimerTick = 5000;
                    if(udsClient.UDSSerNum != 0x36)
                    {
                        showSize = udsClient.m_pstPDUMsg.xDataLen;
                    }
                    else
                    {
                        showSize = 0x10;
                    }
                    message += QString("%1").arg(udsClient.m_pstPDUMsg.xUdsId,3,16,QLatin1Char(' ')).toUpper();
                    for(uint16_t idx = 0; idx < showSize; idx++)
                    {
                        message = message + " " + QString("%1").arg(udsClient.m_pstPDUMsg.aDataBuf[idx],2,16,QLatin1Char('0')).toUpper();
                    }
                    emit updateListMsg(message, 1);
                    break;
                }
            }
        }
    }
}

void FlashExecutor::Tick100ms()
{
    if(S3TimerTick >= 100)
    {
        S3TimerTick -= 100;
    }
    TxProcessHandle();
}

void FlashExecutor::handleRxMsg(sCANObj msg)
{
    uint8_t sameLen = 0;
    if(UdsTp::IsReceivedMsgIDValid(msg.ID))
    {
        if(u8CurrStep < u8TotalStep)
        {
            UdsTp::DriverWriteAFrameInTP(msg.ID, msg.uLen, msg.Data);
            if(UdsTp::DriverReadRespFormTP(&udsClient.m_pstPDUMsg.xUdsId, &udsClient.m_pstPDUMsg.xDataLen, udsClient.m_pstPDUMsg.aDataBuf))
            {
                QString message = "Rx:  ";
                uint8_t type = 0;
                for(uint16_t idx = 0; idx < udsClient.m_pstPDUMsg.exDataLen; idx++)
                {
                    if(udsClient.m_pstPDUMsg.aDataBuf[idx] == udsClient.m_pstPDUMsg.exDataBuf[idx])
                    {
                        sameLen++;
                    }
                }
                if(sameLen == udsClient.m_pstPDUMsg.exDataLen)
                {
                    if(flashInfor.at(u8CurrStep).toObject().value("other").toObject().value("isVersion").toString().compare("true") == 0)
                    {
                        if(flashInfor.at(u8CurrStep).toObject().value("other").toObject().value("strLength").toString().toUShort(nullptr, 16) > 0)
                        {
                            emit updateVersion(&udsClient.m_pstPDUMsg.aDataBuf[3], flashInfor.at(u8CurrStep).toObject().value("other").toObject().value("strLength").toString().toUShort(nullptr, 16));
                        }
                    }
                    u8CurrStep++;
                    if(S3TimerTick > 0)
                    {
                        u8ReceSuccFlag = true;
                    }
                    else
                    {
                        u8ReceSuccFlag = false;
                    }
                    if(udsClient.m_pstPDUMsg.aDataBuf[0] == 0x74)
                    {
                        if(udsClient.m_pstPDUMsg.aDataBuf[1] >> 4 == 0x01)
                        {
                            ActionFlow.tranSize = udsClient.m_pstPDUMsg.aDataBuf[2] - 2;
                        }
                        else if(udsClient.m_pstPDUMsg.aDataBuf[1] >> 4 == 0x02)
                        {
                            ActionFlow.tranSize = (udsClient.m_pstPDUMsg.aDataBuf[2] << 8) + udsClient.m_pstPDUMsg.aDataBuf[3] - 2;
                        }
                        ActionFlow.dataIdx = 0;
                        ActionFlow.blockIdx = 1;
                    }
                    else if(udsClient.m_pstPDUMsg.aDataBuf[0] == 0x76)
                    {
                        if(ActionFlow.dataIdx < ActionFlow.rqstSize)
                        {
                            u8CurrStep--;
                        }
                    }
                    else if(udsClient.m_pstPDUMsg.aDataBuf[0] == 0x77)
                    {
                        ActionFlow.receCrc = (udsClient.m_pstPDUMsg.aDataBuf[1] << 8) + udsClient.m_pstPDUMsg.aDataBuf[2];
                        if(ActionFlow.receCrc == ActionFlow.caclCrc)
                        {
                            u8ReceSuccFlag = true;
                        }
                    }
                }
                if(udsClient.m_pstPDUMsg.aDataBuf[0] == 0x7F)
                {
                    if(udsClient.m_pstPDUMsg.aDataBuf[2] == 0x78)
                    {
                        if(udsClient.m_pstPDUMsg.aDataBuf[1] == (udsClient.m_pstPDUMsg.exDataBuf[0] - 0x40))
                        {
                            u8ReceSuccFlag = false;
                            S3TimerTick = 5000;
                            type = 1;
                        }
                    }
                    else
                    {
                        type = 2;
                    }
                }
                message += QString("%1").arg(udsClient.m_pstPDUMsg.xUdsId,3,16,QLatin1Char(' ')).toUpper();
                for(uint16_t idx = 0; idx < udsClient.m_pstPDUMsg.xDataLen; idx++)
                {
                    message = message + " " + QString("%1").arg(udsClient.m_pstPDUMsg.aDataBuf[idx],2,16,QLatin1Char('0')).toUpper();
                }
                emit updateListMsg(message, type);
            }
        }
    }
}

void FlashExecutor::setAppPath(QString Path)
{
    AppPath = Path;
}

QString FlashExecutor::getAppPath()
{
    return AppPath;
}
